perm filename RECOG2.SAI[SYS,HE] blob
sn#021170 filedate 1973-01-20 generic text, type T, neo UTF8
COMMENT ⊗ VALID 00011 PAGES
RECORD PAGE DESCRIPTION
00001 00001
00002 00002 ENTRY DUMMY
00004 00003 α NEXTL
00005 00004 α GNEXTL
00006 00005 α COMPARE
00010 00006 α MATCHLINES
00012 00007 α FINDX
00016 00008 α BASE_EDGES - HEURISTIC BASE DETECTOR
00021 00009 α SUPPORT
00024 00010 α MAKEPP
00025 00011 α FINDEDGELENGTHS
00030 ENDMK
⊗;
ENTRY DUMMY;
BEGIN "RECOG2.SAI"
REQUIRE 250 PNAMES;
REQUIRE "PREAMB.SAI[SYS,HE]" SOURCE_FILE;
REQUIRE "CPXSYM.AUX[SYS,HE]" SOURCE_FILE;
REQUIRE "RECCOM.AUX[SYS,HE]" SOURCE_FILE;
REQUIRE "RECDPY.HDR[SYS,HE]" SOURCE_FILE;
α LOCALS;
INTEGER FLAG,ERRFLAG;
α EXTERNAL PROCEDURES;
ERP SQRT(REAL X);
EBP COLINEAR(ITEMVAR L1,L2);
EP CROSS_PROD(REFERENCE SAFE REAL ARRAY A,B,C);
ERP DIST(SAFE REAL ARRAY ITEMVAR P1,P2);
ERP DOT_PROD(REFERENCE SAFE REAL ARRAY A,B);
ESP GENSYM(INTEGER ITEMVAR X);
EP INITIALIZE(SAFE REAL ARRAY A);
EP INVERT(SAFE REAL ARRAY A,AI);
EP MATMULT(SAFE REAL ARRAY A,B,C; INTEGER N);
EBP ONLINE(ITEMVAR L;SAFE REAL ARRAY ITEMVAR P);
EBP PARALLEL(ITEMVAR V1,V2);
ESP PRINTNAME(ITEMVAR X);
EBP VERT(ITEMVAR E);
EP VERT_LINE_PT(SAFE REAL ARRAY ITEMVAR T,B);
EXTERNAL INTEGER
DDX,DDY;
EXTERNAL REAL
DISX,DISY,MAGX,MAGY,SDY;
α NEXTL
returns the next line going from L1 to L2 on face F if there
is one, else returns nil.;
INTERNAL ITEMVAR PROCEDURE NEXTL(ITEMVAR L1,L2,F);
BEGIN "NEXTL"
ITEMVAR P,L;
SET S;
P←COP(ENDPT⊗L2-(ENDPT⊗L1∩ENDPT⊗L2));
S ← ENDPT ` P ∩ BOUNDARY ⊗ F ;
IF LENGTH (S) = 2 THEN
RETURN (COP (S - { L2}))
ELSE
RETURN(NIL);
END "NEXTL";
α GNEXTL
returns the next line going from L1 to L2 on face F if there
is one, elle returns nil.;
INTERNAL ITEMVAR PROCEDURE GNEXTL(ITEMVAR L1,L2,F);
BEGIN "GNEXTL"
SET STEMP;
ITEMVAR P,L;
TYPE "GNEXTL - ENTERED" EOM;
TYPE TAB&"LINES:"&PRINTNAME(L1)&" "&PRINTNAME(L2)&
" FACE:"&PRINTNAME(F) EOM;
P←COP(GLB ENDPT⊗L2-(GLB ENDPT⊗L1∩ GLB ENDPT⊗L2));
STEMP←(GLB ENDPT`P) ∩ (GLB BOUNDARY⊗F);
IF LENGTH(STEMP)=2
THEN BEGIN
L←COP(STEMP - {L2});
TYPE TAB&"NEXT LINE="&PRINTNAME(L) EOM;
RETURN (L);
END
ELSE
RETURN(NIL);
END "GNEXTL";
α COMPARE
look at the original camera image and the constructed
graphics image and decide if they are the same ???;
INTERNAL PROCEDURE COMPARE;
BEGIN "COMPARE"
REAL CXMIN,CXMAX,CYMIN,CYMAX,
GXMIN,GXMAX,GYMIN,GYMAX,
XMIN,XMAX,YMIN,YMAX, DX,DY,
MAGX,MAGY;
SET GVERTS;
SAFE REAL ARRAY ITEMVAR GP,P;
ITEMVAR GL,L;
CXMIN←GXMIN←CYMIN←GYMIN←1000;
CXMAX←GXMAX←CYMAX←GYMAX←-1000;
∀ GL|$ LINE⊗SCENE≡GL DO
⊂ L←NEW; MAKE LINE⊗GL≡L ⊃;
∀ GP|$ POINT⊗SCENE≡GP DO
⊂ P←NEW($ ∂(GP));
MAKE POINT⊗GP≡P;
∂(P)[2] ← SDY - ∂(P)[2];
IF ∂(P)[1] < CXMIN
THEN CXMIN← ∂(P)[1]
ELSE IF ∂(P)[1] > CXMAX
THEN CXMAX← ∂(P)[1];
IF ∂(P)[2] < CYMIN
THEN CYMIN← ∂(P)[2]
ELSE IF ∂(P)[2] > CYMAX
THEN CYMAX← ∂(P)[2] ⊃;
TYPE "CAMERA XMIN="&CVG(CXMIN)&" CXMAX="&CVG(CXMAX)&↓&
TAB&"CAMERA YMIN="&CVG(CYMIN)&" CYMAX="&CVG(CYMAX) EOM;
∀ GP,P|$ POINT⊗SCENE≡GP ∧ POINT⊗GP≡P DO
⊂ ∂(P)[1]←∂(P)[1]-CXMIN;
∂(P)[2]←∂(P)[2]-CYMIN ⊃;
GVERTS←PHI;
∀ GL|$ VISIBLE⊗SCENE≡GL DO
⊂ GVERTS←GVERTS ∪ $ ENDPT⊗GL;
L←NEW; MAKE VISIBLE⊗GL≡L ⊃;
∀ GP|GPεGVERTS DO
⊂ P←NEW($ ∂(GP));
MAKE VISIBLE⊗GP≡P;
IF $ ∂(GP)[1] < GXMIN
THEN GXMIN← $ ∂(GP)[1]
ELSE IF $ ∂(GP)[1] > GXMAX
THEN GXMAX← $ ∂(GP)[1];
IF $ ∂(GP)[2] < GYMIN
THEN GYMIN←$ ∂(GP)[2]
ELSE IF $ ∂(GP)[2] > GYMAX
THEN GYMAX←$ ∂(GP)[2] ⊃;
∀ GP,P|GPεGVERTS ∧ VISIBLE⊗GP≡P DO
⊂ ∂(P)[1]←∂(P)[1]-GXMIN;
∂(P)[2]←∂(P)[2]-GYMIN ⊃;
TYPE "GRAPHIC XMIN="&CVG(GXMIN)&" GXMAX="&CVG(GXMAX)&↓&
TAB&"GRAPHIC YMIN="&CVG(GYMIN)&" GYMAX="&CVG(GYMAX) EOM;
XMIN← CXMIN MIN GXMIN;
XMAX← CXMAX MAX GXMAX;
YMIN← CYMIN MIN GYMIN;
YMAX← CYMAX MAX GYMAX;
DX←XMAX-XMIN + 10;
DY←YMAX-YMIN + 10;
MAGX←MAGY←(IF DX/DY > 1 THEN DDX/DX ELSE DDY/DY);
DISX← 5;
DISY← 5;
TYPE "DISX="&CVG(DISX)&TAB&"DISY="&CVG(DISY) EOM;
∀ GP,P|$ POINT⊗SCENE≡GP ∧ POINT⊗GP≡P DO
⊂ ∂(P)[6]← MAGX*∂(P)[1]+DISX;
∂(P)[7]← MAGY*∂(P)[2]+DISY ⊃;
∀ GP,P|GPεGVERTS ∧ VISIBLE⊗GP≡P DO
⊂ ∂(P)[6]← MAGX*∂(P)[1]+DISX;
∂(P)[7]← MAGY*∂(P)[2]+DISY ⊃;
DPYSET(DPYAA);
DPYBIG(TEXT);
∀ GP,P|$ POINT⊗SCENE≡GP ∧ POINT⊗GP≡P DO
⊂ AIVECT(#X(P),#Y(P)); DPYSST("O") ⊃;
DPYOUT(APOG);
DPYLAB("THE CAMERA SCENE.");
DPYSET(DPYAA);
DPYBIG(TEXT);
∀ GP,P|GPεGVERTS ∧ VISIBLE⊗GP≡P DO
⊂ AIVECT(#X(P),#Y(P)); DPYSST("x") ⊃;
DPYOUT(BPOG);
DPYINFO("WAITING");
DPYLAB("ADD THE GRAPHIC SCENE.");
END "COMPARE";
α MATCHLINES
matches lines on F and MF.
F is an object face and MF is a model face.
L1 and L2 on object match ML1 and ML2 on model respectively.;
INTERNAL PROCEDURE MATCHLINES(ITEMVAR F,MF,L1,L2,ML1,ML2);
BEGIN "MATCHLINES"
ITEMVAR L,LX,MLX,ML,MLA,MLB,LA,LB;
TYPE "MATCHLINES - ENTERED"&↓&
TAB&"BODY FACE:"&PRINTNAME(F)&↓&
TAB&"BODY LINES:"&PRINTNAME(L1)&" "&PRINTNAME(L2)&↓&
TAB&"MODEL FACE:"&PRINTNAME(MF)&↓&
TAB&"MODEL LINES:"&PRINTNAME(ML1)&" "&PRINTNAME(ML2) EOM;
LX←L2; MLX←ML2;
L←NEXTL(L1,L2,F); ML←GNEXTL(ML1,ML2,MF);
WHILE L≠L1 ∧ L≠NIL DO
BEGIN
IF ¬MATCH⊗L≡ANY THEN MAKE MATCH⊗L≡ML;
LA←LX;
LX←LB←L;
L←NEXTL(LA,LB,F);
MLA←MLX;
MLX←MLB←ML;
ML←GNEXTL(MLA,MLB,MF);
END;
IF L=L1
THEN BEGIN
TYPE TAB&"RETURN FROM MATCHLINES (1)" EOM;
RETURN;
END;
L1↔L2; ML1↔ML2;
LX←L2; MLX←ML2;
L←NEXTL(L1,L2,F); ML←GNEXTL(ML1,ML2,MF);
WHILE L≠L1 ∧ L≠NIL DO
BEGIN
IF ¬MATCH⊗L≡ANY THEN MAKE MATCH⊗L≡ML;
LA←LX;
LX←LB←L;
L←NEXTL(LA,LB,F);
MLA←MLX;
MLX←MLB←ML;
ML←GNEXTL(MLA,MLB,MF);
END;
TYPE TAB&"RETURN FROM MATCHLINES (2)" EOM;
RETURN;
END "MATCHLINES";
α FINDX
finds the 4X4 translation-rotation matrix necessary to take
MX1,MX2,MX3 of prototype P into X1,X2,X3 of body B.;
INTERNAL PROCEDURE FINDX(SAFE REAL ARRAY ITEMVAR B,P,X1,X2,X3,MX1,MX2,MX3);
BEGIN "FINDX"
INTEGER I,J;
REAL MAG,MAGV2,MAGV3,MAGMV2,MAGMV3;
SAFE REAL ARRAY ITEMVAR X,GB;
SAFE REAL ARRAY MX2R,V2,V3,MV2,MV3,U1,U2,U3,MU1,MU2,MU3[1:3];
SAFE REAL ARRAY R1,R2,R2T,R[1:3,1:3],TT[1:4,1:4];
TYPE "FINDX - ENTER" EOM;
TYPE TAB&"BODY:"&PRINTNAME(B)&↓&
TAB&"PROTOTYPE:"&PRINTNAME(P) EOM;
MAGV2←MAGV3←MAGMV2←MAGMV3←0.0;
FOR I←1 S1U 3 DO
BEGIN
V2[I]←∂(X1)[I+2]-∂(X2)[I+2];
V3[I]←∂(X3)[I+2]-∂(X2)[I+2];
MV2[I]←GLB ∂(MX1)[I]-GLB ∂(MX2)[I];
MV3[I]←GLB ∂(MX3)[I]-GLB ∂(MX2)[I];
MAGV2←MAGV2+V2[I]↑2;
MAGV3←MAGV3+V3[I]↑2;
MAGMV2←MAGMV2+MV2[I]↑2;
MAGMV3←MAGMV3+MV3[I]↑2;
END;
IF MAGV3 > MAGV2
THEN BEGIN
MAGV2↔MAGV3;
MAGMV2↔MAGMV3;
FOR I←1 S1U 3 DO
BEGIN
V2[I]↔V3[I];
MV2[I]↔MV3[I];
END;
END;
FOR I←1 S1U 3 DO
BEGIN
U2[I]←V2[I]/SQRT(MAGV2);
U3[I]←V3[I]/SQRT(MAGV3);
MU2[I]←MV2[I]/SQRT(MAGMV2);
MU3[I]←MV3[I]/SQRT(MAGMV3);
END;
CROSS_PROD(U3,U2,U1);
MAG←SQRT(DOT_PROD(U1,U1));
FOR I←1 S1U 3 DO U1[I]←U1[I]/MAG;
CROSS_PROD(MU3,MU2,MU1);
MAG←SQRT(DOT_PROD(MU1,MU1));
FOR I←1 S1U 3 DO MU1[I]←MU1[I]/MAG;
CROSS_PROD(U2,U1,U3);
CROSS_PROD(MU2,MU1,MU3);
FOR I←1 S1U 3 DO
BEGIN
R1[I,1]←U1[I];
R1[I,2]←U2[I];
R1[I,3]←U3[I];
R2[I,1]←MU1[I];
R2[I,2]←MU2[I];
R2[I,3]←MU3[I];
END;
FOR I←1 S1U 3 DO
FOR J←1 S1U 3 DO R2T[I,J]←R2[J,I];
MATMULT(R1,R2T,R,3);
FOR I←1 S1U 3 DO
BEGIN
MAG←SQRT(R[I,1]↑2 + R[I,2]↑2 + R[I,3]↑2);
FOR J←1 S1U 3 DO R[I,J]←R[I,J]/MAG;
END;
FOR I←1 S1U 3 DO
FOR J←1 S1U 3 DO TT[I,J]←R[I,J];
TT[4,1]←TT[4,2]←TT[4,3]←0.0;TT[4,4]←1.0;
FOR I←1 S1U 3 DO
BEGIN
MX2R[I]←0.0;
FOR J←1 S1U 3 DO MX2R[I]←MX2R[I]+R[I,J]*GLB ∂(MX2)[J];
END;
FOR I←1 S1U 3 DO TT[I,4]←∂(X2)[I+2]-MX2R[I];
TYPE TAB&"INSTANCE TRANSFORM FOR BODY:" EOM;
FOR I←1 S1U 4 DO
TYPE TAB&CVG(TT[I,1])&" "&CVG(TT[I,2])&" "&CVG(TT[I,3])&" "&CVG(TT[I,4]) EOM;
GB←GLB NEW(TT);
MAKE OMATCH⊗GB≡B;
GLB MAKE INSTANCE⊗P≡GB;
X←GLB NEW(FOURBY4);
GLB MAKE INVERSE⊗GB≡X;
INVERT(TT,GLB ∂(X));
TYPE TAB&"FINDX - EXIT" EOM;
END "FINDX";
α BASE_EDGES - HEURISTIC BASE DETECTOR
;
INTERNAL SET PROCEDURE BASE_EDGES(ITEMVAR B);
BEGIN "BASE EDGES"
SET ITEMVAR BS;
ITEMVAR L,F,L1,L2;
STRING STR1;
SET S,S1,S2,S3,S4;
SAFE REAL ARRAY ITEMVAR P,W,X,Y,TOP,BOTTOM,Z,V1,V2,V3;
REAL SLOPE1,SLOPE2;
α only exterior edges are candidates for base edges;
TYPE "BASE_EDGES - ENTERED" EOM;
ASSIGN BS|EXTERIOR⊗B≡BS HOLDS;
S←∂(BS);
TYPE TAB&"EXTERIOR EDGES: " EOS;
∀ X|XεS DO TYPE PRINTNAME(X)&" " EOS;
TYPE "DONE" EOM;
α exclude vertical edges from potential base edges;
S1←PHI;
S2←LINE⊗B;
∀ X|XεS DO
IF VERT(X)
THEN BEGIN
LABEL LAB1;
S3←ENDPT⊗X;
TOP←LOP(S3);
BOTTOM←COP(S3);
IF ∂(TOP)[2]<∂(BOTTOM)[2]
THEN TOP↔BOTTOM;
IF LENGTH(( ENDPT`BOTTOM)∩(LINE⊗B))=3
THEN GO TO LAB1;
PUT X IN S1;
IF XεS
THEN REMOVE X FROM S;
LAB1:
END;
α also exclude edges adjacent to the vertical edges at their tops;
∀ X | XεS DO
∀ Y | YεS1 DO
BEGIN
S2←(ENDPT⊗X)∩(ENDPT⊗Y);
IF S2≠PHI
THEN BEGIN
S3←ENDPT⊗Y;
TOP←LOP(S3);
BOTTOM←COP(S3);
IF ∂(TOP)[2]<∂(BOTTOM)[2]
THEN TOP↔BOTTOM;
Z←COP(S2);
IF Z=TOP
THEN BEGIN
REMOVE X FROM S;
PUT X IN S1;
DONE;
END;
END;
END;
α remove edges at "concave down" L vertices;
S2←POINT⊗B;
∀ V3|V3εS2 DO
BEGIN
S3←ENDPT`V3∩LINE⊗B;
IF LENGTH(S3)=2
THEN BEGIN
X←LOP(S3);
S4←ENDPT⊗X;
REMOVE V3 FROM S4;
V1←COP(S4);
Y←COP(S3);
S4←ENDPT⊗Y;
REMOVE V3 FROM S4;
V2←COP(S4);
IF ∂(V3)[2]≥∂(V1)[2] ∧ ∂(V3)[2]≥∂(V2)[2]
THEN BEGIN
S←S-{X,Y};
PUT X IN S1;
PUT Y IN S1;
END;
END;
END;
α remove edges at "concave down" exterior ARROW vertices.;
∀ L,P|LεS ∧ ENDPT⊗L≡P ∧ FLAVOR⊗P≡ARROW DO
BEGIN
ASSIGN Y|ENDPT⊗Y≡P ∧ (YεSHAFTS) HOLDS;
V1←COP(ENDPT⊗Y-{P});
IF ∂(V1)[7]<∂(P)[7]
THEN BEGIN
S4←ENDPT`P∩LINE⊗B-SHAFTS;
X←LOP(S4);
Y←COP(S4);
S←S-{X,Y};
PUT X IN S1;
PUT Y IN S1;
END;
END;
α if colinear segments have not yet been extended, do not
let one part of an edge be part of the base and another
part not be part of the base.;
∀ X,Y| XεS AND YεS1 AND (COLINEAR(X,Y)) DO
BEGIN
REMOVE X FROM S;
PUT X IN S1;
END;
α don't keep two lines as base edges on any one visible face.;
∀ F|FACE⊗B≡F DO
BEGIN
S2←BOUNDARY⊗F∩S;
IF LENGTH(S2)>1
THEN BEGIN
L1←LOP(S2);L2←COP(S2);
S2←ENDPT⊗L1;
X←LOP(S2);
Y←COP(S2);
S2←ENDPT⊗L2;
Z←LOP(S2);
W←COP(S2);
SLOPE1←(∂(X)[2]-∂(Y)[2])/(∂(X)[1]-∂(Y)[1]);
SLOPE2←(∂(Z)[2]-∂(W)[2])/(∂(Z)[1]-∂(W)[1]);
IF ABS(SLOPE1)>ABS(SLOPE2)
THEN REMOVE L1 FROM S
ELSE REMOVE L2 FROM S;
END;
END;
α subject to applied heuristics set S contains the "base" edges
of the body.;
STR1←PRINTNAME(B);
IF S=PHI
THEN TYPE TAB&"NO BASE EDGES VISIBLE FOR BODY "&STR1 EOM
ELSE ∀ X| XεS DO
BEGIN
S4←ENDPT⊗X;
V1←LOP(S4);
V2←COP(S4);
TYPE TAB&"BASE EDGE OF BODY "&STR1&" IS "&PRINTNAME(X)
&" ("&PRINTNAME(V1)&","&PRINTNAME(V2)&")" EOM;
END;
S1←S2←S3←S4←PHI;
RETURN (S);
END "BASE EDGES";
α SUPPORT
the mumbo jumbo which follows is supposed to set up associations
giving the binary relationships between bodies.
For examble, if object A rests on object B, then we will
hopefully set up an association "SUPPORTER⊗A≡B".
The decisions here are based only on 2-D information.
Later during the recognition process 3-D information
is used to rule out some of the potential supporters.;
INTERNAL PROCEDURE SUPPORT(ITEMVAR B1,B2);
BEGIN "SUPPORT"
ITEMVAR E,L,LA,R2,F2;
SET S1,S2;
SET ITEMVAR X;
STRING STR;
∀ E|EDGE⊗S≡E DO
BEGIN
LABEL LAB1;
IF LENGTH(BOUNDARY`E)=1 THEN GO TO LAB1;
L←NEW;
NEW_PNAME(L,GENSYM(NEWL));
S1←BOUNDARY`E∩AREA⊗B1;
S2←BOUNDARY`E∩AREA⊗B2;
IF S1≠PHI ∧ S2≠PHI
THEN BEGIN
ASSIGN X|BASE⊗B1≡X HOLDS;
∀ LA|LAε∂(X) DO
IF LA=L ∨ SON⊗LA≡L
THEN BEGIN
MAKE SUPPORTER⊗B1≡B2;
R2←COP(S2);
IF LENGTH(AREA`R2∩BODY⊗S)=1
THEN BEGIN
STR←PRINTNAME(R2)[5 TO INF];
STR←":"&STR;
F2←NEW;NEW_PNAME(F2,STR);
IF SON⊗ANY≡F2 THEN F2←COP(SON`F2);
END
ELSE IF LENGTH(AREA`R2∩BODY⊗S)=2
THEN BEGIN
STR←PRINTNAME(R2)[5 TO INF];
STR←":"&STR;
R2←NEW;NEW_PNAME(R2,STR);
ASSIGN F2|FACE⊗B2≡F2 ∧ PARENT⊗F2≡R2 HOLDS;
END
ELSE BEGIN
TYPE "SUPPORT - TOO MANY MISSING LINES." EOM;
S1←S2←PHI;
RETURN;
END;
MAKE TOP⊗B2≡F2;
END;
END;
LAB1:
END;
S1←S2←PHI;
RETURN;
END "SUPPORT";
α MAKEPP
sets up associations representing the fact that prototype
PRO has a view where V vertices and F faces are visible.
D=0 implies that this is a degenerate view, D=1 says that
the view is not degenerate.;
INTERNAL PROCEDURE MAKEPP(ITEMVAR PRO; INTEGER F,V,D);
BEGIN "MAKEPP"
SAFE INTEGER ARRAY ITEMVAR X;
X←NEW(SIZE3);
MAKE PPAIR⊗PRO≡X;
∂(X)[1]←F;
∂(X)[2]←V;
∂(X)[3]←D;
END "MAKEPP";
α FINDEDGELENGTHS
try to set up the lengths of the various edges of the
scene as the datums of the corresponding edge items.
Edges that are occluded are represented by a length
minus the length of the visible portion.
Only a few of the edge lengths are set up, i.e., base edges,
vertical edges, and lines parallel to edges of known length
and on the same face.;
INTERNAL PROCEDURE FINDEDGELENGTHS(ITEMVAR B);
BEGIN "FINDEDGELENGTHS"
SET ITEMVAR X;
SET S;
SAFE REAL ARRAY ITEMVAR V1,V2,U,V;
REAL ITEMVAR L,Y,F;
REAL LEN,IDIST1,IDIST2;
BOOLEAN BOOL1;
TYPE "FINDEDGELENGTHS - ENTERED" EOM;
∀ L|LINE⊗B≡L DO ∂(L)←0.0;
α set up the lengths of the base edges;
ASSIGN X|BASE⊗B≡X HOLDS;
∀ L|Lε∂(X) DO
BEGIN
S←ENDPT⊗L;
V1←LOP(S);
V2←COP(S);
LEN←SQRT((∂(V1)[3]-∂(V2)[3])↑2+
(∂(V1)[4]-∂(V2)[4])↑2);
IF (LENGTH(ENDPT`V1∩LINE⊗B)=1)∨(LENGTH(ENDPT`V2∩LINE⊗B)=1)
THEN ∂(L)←-LEN
ELSE ∂(L)←LEN;
TYPE TAB&"BASE EDGE: "&PRINTNAME(V1)&" "&PRINTNAME(V2)&" "&CVG(
∂(L)) EOM;
END;
α now do the vertical edges.;
VERTICALS←PHI;
∀ L|LINE⊗B≡L ∧ (¬LεBASES) DO
IF VERT(L) THEN PUT L IN VERTICALS;
∀ L|LεVERTICALS DO
BEGIN
LABEL L1;
BOOL1←FALSE;
∀ Y|Yε∂(X) DO
IF ADJ(L,Y) THEN BOOL1←TRUE;
IF ¬BOOL1 THEN GO TO L1;
S←ENDPT⊗L;
U←LOP(S);
V←COP(S);
TYPE TAB&"Z COOR:"&CVG(∂(U)[5])&" "&CVG(∂(V)[5]) EOM;
IF ∂(U)[2]<∂(V)[2] THEN U↔V;
VERT_LINE_PT(U,V);
LEN←SQRT((∂(U)[3]-∂(V)[3])↑2+
(∂(U)[4]-∂(V)[4])↑2+
(∂(U)[5]-∂(V)[5])↑2);
IF (LENGTH(ENDPT`U∩LINE⊗B)=1)∨(LENGTH(ENDPT`V∩LINE⊗B)=1)
THEN ∂(L)←-LEN
ELSE ∂(L)←LEN;
TYPE TAB&"VERTICAL:"&PRINTNAME(U)&" "&PRINTNAME(V)&" "&CVG(∂(L))
EOM;
L1:
END;
α now those edges parallel to edges of known length.;
∀ F|FACE⊗B≡F DO
∀ L|BOUNDARY⊗F≡L DO
IF ∂(L)=0 THEN
∀ Y|BOUNDARY⊗F≡Y ∧ (Y≠L) ∧ (ABS(∂(Y))>0)
∧ ((ENDPT⊗L∩ENDPT⊗Y)=PHI) ∧ (PARALLEL(L,Y)) DO
BEGIN
S←ENDPT⊗Y;
U←LOP(S);
V←COP(S);
IDIST1←DIST(U,V);
S←ENDPT⊗L;
U←LOP(S);
V←COP(S);
IDIST2←DIST(U,V);
LEN←ABS(∂(Y))*IDIST2/IDIST1;
IF (LENGTH(ENDPT`U∩LINE⊗B)=1)∨(LENGTH(ENDPT`V∩LINE⊗B)=1)
THEN
∂(L)←-LEN ELSE ∂(L)←LEN;
TYPE TAB&"PARALLEL:"&PRINTNAME(U)&" "&PRINTNAME(V)&
" "&CVG(∂(L)) EOM;
END;
TYPE TAB&"FINDEDGELENGTHS - EXIT" EOM;
S←PHI;
RETURN;
END "FINDEDGELENGTHS";
END "RECOG2.SAI";